/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

#ifndef TEST_UTILS_HH
#define TEST_UTILS_HH

/*! @file test/Utils.hh
    @brief Usefull functions and classes.
    @author @ref Guillaume_Terrissol
    @date 15th February 2010 - 10th March 2014
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <cstdio>
#include <string>
#include <vector>

#include <BundleFactory.hh>

namespace CHK
{
    /*! @brief System stream redirection.
        @version 0.95

        Instantiates this class allows to redirect (RAII-style) a stream (stdout or stderr) contents to a file.
     */
    class RedirectStream
    {
    public:
        //! @name Constructor & destructor
        //@{
        RedirectStream(const char* pFileName, FILE* pStream);   //!< Constructor.
        ~RedirectStream();                                      //!< Destructor.
        //@}

    private:
        //! @name File descriptors
        int     mOrigin;                                        //!< ... original.
        int     mDuplicate;                                     //!< ... duplicated.
        void*   mNewFile;                                       //!< Reopened file.
        //@}
    };


    /*! @brief Output stream of a system command.
        @version 0.9

        Instantiates this class allows to retrieve, as a string, the output text of a system command.
     */
    class CommandDump
    {
    public:
        //! @name Interface
        //@{
                            CommandDump(const std::string& pCommand);   //!< Constructor.
        const std::string&  output() const;                             //!< Output text.
        //@}

    private:

        std::string mOutput;                                            //!< Output.
    };


    //! @name File handling functions
    //@{
    void    installBundle(const std::string& pName);                    //!< Bundle installing.
    void    removeBundles();                                            //!< Bundle removing.
    bool    compareFiles(const std::string& pL, const std::string& pR); //!< File comparison.
    bool    isFileEmpty(const std::string& pName);                      //!< File emptiness.
    //@}


    extern  const std::string   kSuspended;
    extern  const std::string   kPause;
    extern  const std::string   kResume;


    /*! @brief Custom bundle factory.
        @version 0.6
     */
    class ValidBundleFactory : public OSGi::BundleFactory
    {
    public:
        //! @name Constructor & destructor
        //@{
                            ValidBundleFactory();                                   //!< Constructor.
virtual                     ~ValidBundleFactory();                                  //!< Destructor.
        //@}

    protected:

virtual void                setUp(OSGi::LifeCycle::Ptr pLifeCycle) const override;  //!< Life cycle definition.


    private:

virtual OSGi::Bundle::Ptr   doMakeBundle(std::string pFileName,
                                         int         pId,
                                         ContextCPtr pContext) const override;      //!< Bundle creation.
    };


    /*! @brief Custom bundle.
        @version 0.6
     */
    class ValidBundle : public OSGi::Bundle
    {
    public:

        friend class ValidBundleFactory;
        //! @name Constructor & destructor
        //@{
                ValidBundle(std::string pFileName, int pId, const ContextCPtr pContext);    //!< Constructor.
virtual         ~ValidBundle();                                                             //!< Destructor.
        //@}

    private:

        bool    suspend(ContextPtr pContext);                                               //!< Bundle suspension.
        bool    resume(ContextPtr pContext);                                                //!< Bundle resumption.

        ContextCPtr mContext;                                                               //!< Context.
        bool        mIsPaused;                                                              //!< Pause status.
    };
}

#endif  // De BIN_UTILS_HH
